/*
 * MatrixBuilder.cs
 * 
 * Copyright (c) 2005-2006, dnAnalytics. All rights reserved.
*/

using System;
using dnAnalytics.LinearAlgebra.Native;
using dnAnalytics.Resources;

namespace dnAnalytics.LinearAlgebra
{
    /// <summary>
    /// A static class used to create <see cref="Matrix"/> objects.
    /// </summary>
    public static class MatrixBuilder
    {

        /// <summary>
        /// Creates a <see cref="Matrix"/> with the given order. All elements are initialized to zero. The 
        /// storage type used is determined by <see cref="Settings.DefaultMatrixType"/>.
        /// </summary>
        /// <param name="order">The order of the <see cref="Matrix"/> to create.</param>
        /// <returns>A <see cref="Matrix"/> with the requested order.</returns>
        /// <remarks><see cref="Settings.DefaultMatrixType"/> determines the storage type to use and, <see cref="Settings.UseNativeLibrary"/> 
        /// determines whether to use native BLAS and LAPACK routines or not. If native routines are used, <see cref="Settings.Blas"/> 
        /// and <see cref="Settings.Lapack"/> set which <see cref="BlasProvider"/> 
        /// and <see cref="LapackProvider"/> to use, respectively.</remarks>
        /// <exception cref="ArgumentException">If <paramref name="order"/> is not positive.</exception>
        /// <seealso cref="Settings"/>
        /// <seealso cref="BlasProvider"/>
        /// <seealso cref="LapackProvider"/>
        public static Matrix CreateMatrix(int order)
        {
            return CreateMatrix(order, order, Settings.DefaultMatrixType, Settings.UseNativeLibrary);
        }

        /// <summary>
        /// Creates a <see cref="Matrix"/> with the given order. All elements are initialized to zero.
        /// </summary>
        /// <param name="order">The order of the <see cref="Matrix"/> to create.</param>
        /// <param name="type">The type of matrix to create.</param>
        /// <returns>A <see cref="Matrix"/> with the requested order.</returns>
        /// <remarks><see cref="Settings.UseNativeLibrary"/> 
        /// determines whether to use native BLAS and LAPACK routines or not. If native routines are used, <see cref="Settings.Blas"/> 
        /// and <see cref="Settings.Lapack"/> set which <see cref="BlasProvider"/> 
        /// and <see cref="LapackProvider"/> to use, respectively.</remarks>
        /// <exception cref="ArgumentException">If <paramref name="order"/> is not positive.</exception>
        /// <seealso cref="Settings"/>
        /// <seealso cref="BlasProvider"/>
        /// <seealso cref="LapackProvider"/>
        public static Matrix CreateMatrix(int order, MatrixType type)
        {
            return CreateMatrix(order, order, type, Settings.UseNativeLibrary);
        }

        /// <summary>
        /// Creates a <see cref="Matrix"/> with the given order. All elements are initialized to zero. The 
        /// storage type used is determined by <see cref="Settings.DefaultMatrixType"/>.
        /// </summary>
        /// <param name="order">The order of the <see cref="Matrix"/> to create.</param>
        /// <param name="useNativeLibrary">Whether to use native BLAS and LAPACK routines, or not.</param>
        /// <returns>A <see cref="Matrix"/> with the requested order.</returns>
        /// <remarks><see cref="Settings.DefaultMatrixType"/> determines the storage type to use.
        /// If native routines are used, <see cref="Settings.Blas"/> and <see cref="Settings.Lapack"/> 
        /// set which <see cref="BlasProvider"/> and <see cref="LapackProvider"/> to use, respectively.</remarks>
        /// <exception cref="ArgumentException">If <paramref name="order"/> is not positive.</exception>
        /// <seealso cref="Settings"/>
        /// <seealso cref="BlasProvider"/>
        /// <seealso cref="LapackProvider"/>
        public static Matrix CreateMatrix(int order, bool useNativeLibrary)
        {
            return CreateMatrix(order, order, Settings.DefaultMatrixType, useNativeLibrary);
        }

        /// <summary>
        /// Creates a <see cref="Matrix"/> with the given order. All elements are initialized to zero.
        /// </summary>
        /// <param name="order">The order of the <see cref="Matrix"/> to create.</param>
        /// <param name="type">The type of matrix to create.</param>
        /// <param name="useNativeLibrary">Whether to use native BLAS and LAPACK routines, or not.</param>
        /// <returns>A <see cref="Matrix"/> with the requested order.</returns>
        /// <remarks>If native routines are used, <see cref="Settings.Blas"/> and <see cref="Settings.Lapack"/> 
        /// set which <see cref="BlasProvider"/> and <see cref="LapackProvider"/> to use, respectively.</remarks>
        /// <exception cref="ArgumentException">If <paramref name="order"/> is not positive.</exception>
        /// <seealso cref="Settings"/>
        /// <seealso cref="BlasProvider"/>
        /// <seealso cref="LapackProvider"/>
        public static Matrix CreateMatrix(int order, MatrixType type, bool useNativeLibrary)
        {
            return CreateMatrix(order, order, type, useNativeLibrary);
        }

        /// <summary>
        /// Creates a <see cref="Matrix"/> with the given number of rows and columns. All elements are initialized to zero.
        /// </summary>
        /// <param name="rows">The number of rows of the created <see cref="Matrix"/>.</param>
        /// <param name="columns">The number of columns of the created <see cref="Matrix"/>.</param>
        /// <returns>A <see cref="Matrix"/> with the requested number of rows and columns.</returns>
        /// <remarks><see cref="Settings.DefaultMatrixType"/> determines the storage type to use.
        /// Uses <see cref="Settings.UseNativeLibrary"/> to determine whether to use native BLAS and LAPACK routines or not. If
        /// native routines are used, <see cref="Settings.Blas"/> and <see cref="Settings.Lapack"/> set which <see cref="BlasProvider"/> 
        /// and <see cref="LapackProvider"/> to use, respectively.</remarks>
        /// <exception cref="ArgumentException">If <paramref name="rows"/> is not positive.</exception>
        /// <exception cref="ArgumentException">If <paramref name="columns"/> is not positive.</exception>
        /// <seealso cref="Settings"/>
        /// <seealso cref="BlasProvider"/>
        /// <seealso cref="LapackProvider"/>
        public static Matrix CreateMatrix(int rows, int columns)
        {
            return CreateMatrix(rows, columns, Settings.DefaultMatrixType, Settings.UseNativeLibrary);
        }

        /// <summary>
        /// Creates a <see cref="Matrix"/> with the given number of rows and columns. All elements are initialized to zero.
        /// </summary>
        /// <param name="rows">The number of rows of the created <see cref="Matrix"/>.</param>
        /// <param name="columns">The number of columns of the created <see cref="Matrix"/>.</param>
        /// <param name="type">The type of matrix to create.</param>
        /// <returns>A <see cref="Matrix"/> with the requested number of rows and columns.</returns>
        /// <remarks>Uses <see cref="Settings.UseNativeLibrary"/> to determine whether to use native BLAS and LAPACK routines or not. If
        /// native routines are used, <see cref="Settings.Blas"/> and <see cref="Settings.Lapack"/> set which <see cref="BlasProvider"/> 
        /// and <see cref="LapackProvider"/> to use, respectively.</remarks>
        /// <exception cref="ArgumentException">If <paramref name="rows"/> is not positive.</exception>
        /// <exception cref="ArgumentException">If <paramref name="columns"/> is not positive.</exception>
        /// <seealso cref="Settings"/>
        /// <seealso cref="BlasProvider"/>
        /// <seealso cref="LapackProvider"/>
        public static Matrix CreateMatrix(int rows, int columns, MatrixType type)
        {
            return CreateMatrix(rows, columns, type, Settings.UseNativeLibrary);
        }
        /// <summary>
        /// Creates a <see cref="Matrix"/> with the given number of rows and columns. All elements are initialized to zero.
        /// </summary>
        /// <param name="rows">The number of rows of the created <see cref="Matrix"/>.</param>
        /// <param name="columns">The number of columns of the created <see cref="Matrix"/>.</param>
        /// <param name="useNativeLibrary">Whether to use native BLAS and LAPACK routines, or not.</param>
        /// <returns>A <see cref="Matrix"/> with the requested number of rows and columns.</returns>
        /// <remarks><see cref="Settings.DefaultMatrixType"/> determines the storage type to use.
        /// If native routines are used, <see cref="Settings.Blas"/> and <see cref="Settings.Lapack"/> 
        /// set which <see cref="BlasProvider"/> and <see cref="LapackProvider"/> to use, respectively.</remarks>
        /// <exception cref="ArgumentException">If <paramref name="rows"/> is not positive.</exception>
        /// <exception cref="ArgumentException">If <paramref name="columns"/> is not positive.</exception>
        /// <seealso cref="Settings"/>
        /// <seealso cref="BlasProvider"/>
        /// <seealso cref="LapackProvider"/>
        public static Matrix CreateMatrix(int rows, int columns, bool useNativeLibrary)
        {
            return CreateMatrix(rows, columns, Settings.DefaultMatrixType, useNativeLibrary);
        }

        /// <summary>
        /// Creates a <see cref="Matrix"/> with the given number of rows and columns. All elements are initialized to zero.
        /// </summary>
        /// <param name="rows">The number of rows of the created <see cref="Matrix"/>.</param>
        /// <param name="columns">The number of columns of the created <see cref="Matrix"/>.</param>
        /// <param name="type">The type of matrix to create.</param>
        /// <param name="useNativeLibrary">Whether to use native BLAS and LAPACK routines, or not.</param>
        /// <returns>A <see cref="Matrix"/> with the requested number of rows and columns.</returns>
        /// <remarks>If native routines are used, <see cref="Settings.Blas"/> and <see cref="Settings.Lapack"/> 
        /// set which <see cref="BlasProvider"/> and <see cref="LapackProvider"/> to use, respectively.</remarks>
        /// <exception cref="ArgumentException">If <paramref name="rows"/> is not positive.</exception>
        /// <exception cref="ArgumentException">If <paramref name="columns"/> is not positive.</exception>
        /// <seealso cref="Settings"/>
        /// <seealso cref="BlasProvider"/>
        /// <seealso cref="LapackProvider"/>
        public static Matrix CreateMatrix(int rows, int columns, MatrixType type, bool useNativeLibrary)
        {
            if (rows < 1)
            {
                throw new ArgumentException("rows", dnAnalytics.Resources.Strings.NotPositiveException);
            }
            if (columns < 1)
            {
                throw new ArgumentException("columns", dnAnalytics.Resources.Strings.NotPositiveException);
            }

            Matrix ret = null;
            switch (type)
            {
                case MatrixType.Dense:
                    ret = new DenseMatrix(rows, columns, useNativeLibrary);
                    break;
                case MatrixType.Sparse:
                    ret = new SparseMatrix(rows, columns);
                    break;
            }
            return ret;
        }

        /// <summary>
        /// Creates a <see cref="Matrix"/> with the given number of rows and columns. All elements are initialized to <paramref name="value"/>.
        /// </summary>
        /// <param name="rows">The number of rows of the created <see cref="Matrix"/>.</param>
        /// <param name="columns">The number of columns of the created <see cref="Matrix"/>.</param>
        /// <param name="value">The value to set all element of the matrix to.</param>
        /// <returns>A <see cref="Matrix"/> with the requested number of rows and columns. All elements are initialized to <paramref name="value"/></returns>
        /// <remarks><see cref="Settings.DefaultMatrixType"/> determines the storage type to use.
        /// Uses <see cref="Settings.UseNativeLibrary"/> to determine whether to use native BLAS and LAPACK routines or not. If
        /// native routines are used, <see cref="Settings.Blas"/> and <see cref="Settings.Lapack"/> set which <see cref="BlasProvider"/> 
        /// and <see cref="LapackProvider"/> to use, respectively.</remarks>
        /// <exception cref="ArgumentException">If <paramref name="rows"/> is not positive.</exception>
        /// <exception cref="ArgumentException">If <paramref name="columns"/> is not positive.</exception>
        /// <seealso cref="Settings"/>
        /// <seealso cref="BlasProvider"/>
        /// <seealso cref="LapackProvider"/>
        public static Matrix CreateMatrix(int rows, int columns, double value)
        {
            return CreateMatrix(rows, columns, value, Settings.DefaultMatrixType, Settings.UseNativeLibrary);
        }

        /// <summary>
        /// Creates a <see cref="Matrix"/> with the given number of rows and columns. All elements are initialized to <paramref name="value"/>.
        /// </summary>
        /// <param name="rows">The number of rows of the created <see cref="Matrix"/>.</param>
        /// <param name="columns">The number of columns of the created <see cref="Matrix"/>.</param>
        /// <param name="value">The value to set all element of the matrix to.</param>
        /// <param name="type">The type of matrix to create.</param>
        /// <returns>A <see cref="Matrix"/> with the requested number of rows and columns. All elements are initialized to <paramref name="value"/></returns>
        /// <remarks>Uses <see cref="Settings.UseNativeLibrary"/> to determine whether to use native BLAS and LAPACK routines or not. If
        /// native routines are used, <see cref="Settings.Blas"/> and <see cref="Settings.Lapack"/> set which <see cref="BlasProvider"/> 
        /// and <see cref="LapackProvider"/> to use, respectively.</remarks>
        /// <exception cref="ArgumentException">If <paramref name="rows"/> is not positive.</exception>
        /// <exception cref="ArgumentException">If <paramref name="columns"/> is not positive.</exception>
        /// <seealso cref="Settings"/>
        /// <seealso cref="BlasProvider"/>
        /// <seealso cref="LapackProvider"/>
        public static Matrix CreateMatrix(int rows, int columns, double value, MatrixType type)
        {
            return CreateMatrix(rows, columns, value, type, Settings.UseNativeLibrary);
        }

        /// <summary>
        /// Creates a <see cref="Matrix"/> with the given number of rows and columns. All elements are initialized to <paramref name="value"/>.
        /// </summary>
        /// <param name="rows">The number of rows of the created <see cref="Matrix"/>.</param>
        /// <param name="columns">The number of columns of the created <see cref="Matrix"/>.</param>
        /// <param name="value">The value to set all element of the matrix to.</param>
        /// <param name="useNativeLibrary">Whether to use native BLAS and LAPACK routines, or not.</param>
        /// <returns>A <see cref="Matrix"/> with the requested number of rows and columns. All elements are initialized to <paramref name="value"/></returns>
        /// <remarks><see cref="Settings.DefaultMatrixType"/> determines the storage type to use.
        /// If native routines are used, <see cref="Settings.Blas"/> and <see cref="Settings.Lapack"/> 
        /// set which <see cref="BlasProvider"/> and <see cref="LapackProvider"/> to use, respectively.</remarks>
        /// <exception cref="ArgumentException">If <paramref name="rows"/> is not positive.</exception>
        /// <exception cref="ArgumentException">If <paramref name="columns"/> is not positive.</exception>
        /// <seealso cref="Settings"/>
        /// <seealso cref="BlasProvider"/>
        /// <seealso cref="LapackProvider"/>
        public static Matrix CreateMatrix(int rows, int columns, double value, bool useNativeLibrary)
        {
            return CreateMatrix(rows, columns, value, Settings.DefaultMatrixType, useNativeLibrary);
        }

        /// <summary>
        /// Creates a <see cref="Matrix"/> with the given number of rows and columns. All elements are initialized to <paramref name="value"/>.
        /// </summary>
        /// <param name="rows">The number of rows of the created <see cref="Matrix"/>.</param>
        /// <param name="columns">The number of columns of the created <see cref="Matrix"/>.</param>
        /// <param name="value">The value to set all element of the matrix to.</param>
        /// <param name="type">The type of matrix to create.</param>
        /// <param name="useNativeLibrary">Whether to use native BLAS and LAPACK routines, or not.</param>
        /// <returns>A <see cref="Matrix"/> with the requested number of rows and columns. All elements are initialized to <paramref name="value"/></returns>
        /// <remarks>If native routines are used, <see cref="Settings.Blas"/> and <see cref="Settings.Lapack"/> 
        /// set which <see cref="BlasProvider"/> and <see cref="LapackProvider"/> to use, respectively.</remarks>
        /// <exception cref="ArgumentException">If <paramref name="rows"/> is not positive.</exception>
        /// <exception cref="ArgumentException">If <paramref name="columns"/> is not positive.</exception>
        /// <seealso cref="Settings"/>
        /// <seealso cref="BlasProvider"/>
        /// <seealso cref="LapackProvider"/>
        public static Matrix CreateMatrix(int rows, int columns, double value, MatrixType type, bool useNativeLibrary)
        {
            Matrix ret = CreateMatrix(rows, columns, type, useNativeLibrary);

            for (int i = 0; i < rows; i++)
            {
                for (int j = 0; j < columns; j++)
                {
                    ret.ValueAt(i, j, value);
                }
            }
            return ret;
        }

        /// <summary>
        /// Creates a <see cref="Matrix"/> from the given <see cref="Vector"/>.
        /// </summary>
        /// <param name="vector">The <see cref="Vector"/> to create the <see cref="Matrix"/> to from.</param>
        /// <param name="columnVector">If <b>true</b>, creates a <b>vector.count x 1</b> <see cref="Matrix"/>;
        /// otherwise, create a creates a <b>1 x vector.count</b> <see cref="Matrix"/>.</param>
        /// <returns>A <see cref="Matrix"/> containing the values of <paramref name="vector"/>.</returns>
        /// <remarks><see cref="Settings.DefaultMatrixType"/> determines the storage type to use and, <see cref="Settings.UseNativeLibrary"/> 
        /// determines whether to use native BLAS and LAPACK routines or not. If native routines are used, <see cref="Settings.Blas"/> 
        /// and <see cref="Settings.Lapack"/> set which <see cref="BlasProvider"/> 
        /// and <see cref="LapackProvider"/> to use, respectively.</remarks>
        /// <exception cref="ArgumentNullException">If <paramref name="vector"/> is <b>null</b>.</exception>
        /// <seealso cref="Settings"/>
        /// <seealso cref="BlasProvider"/>
        /// <seealso cref="LapackProvider"/>
        public static Matrix CreateMatrix(Vector vector, bool columnVector)
        {
            return CreateMatrix(vector, columnVector, Settings.DefaultMatrixType, Settings.UseNativeLibrary);
        }

        /// <summary>
        /// Creates a <see cref="Matrix"/> from the given <see cref="Vector"/>.
        /// </summary>
        /// <param name="vector">The <see cref="Vector"/> to create the <see cref="Matrix"/> to from.</param>
        /// <param name="columnVector">If <b>true</b>, creates a <b>vector.count x 1</b> <see cref="Matrix"/>;
        /// otherwise, create a creates a <b>1 x vector.count</b> <see cref="Matrix"/>.</param>
        /// <param name="type">The type of matrix to create.</param>
        /// <returns>A <see cref="Matrix"/> containing the values of <paramref name="vector"/>.</returns>
        /// <remarks><see cref="Settings.UseNativeLibrary"/> 
        /// determines whether to use native BLAS and LAPACK routines or not. If native routines are used, <see cref="Settings.Blas"/> 
        /// and <see cref="Settings.Lapack"/> set which <see cref="BlasProvider"/> 
        /// and <see cref="LapackProvider"/> to use, respectively.</remarks>
        /// <exception cref="ArgumentNullException">If <paramref name="vector"/> is <b>null</b>.</exception>
        /// <seealso cref="Settings"/>
        /// <seealso cref="BlasProvider"/>
        /// <seealso cref="LapackProvider"/>
        public static Matrix CreateMatrix(Vector vector, bool columnVector, MatrixType type)
        {
            return CreateMatrix(vector, columnVector, type, Settings.UseNativeLibrary);
        }

        /// <summary>
        /// Creates a <see cref="Matrix"/> from the given <see cref="Vector"/>.
        /// </summary>
        /// <param name="vector">The <see cref="Vector"/> to create the <see cref="Matrix"/> to from.</param>
        /// <param name="columnVector">If <b>true</b>, creates a <b>vector.count x 1</b> <see cref="Matrix"/>;
        /// otherwise, create a creates a <b>1 x vector.count</b> <see cref="Matrix"/>.</param>
        /// <param name="useNativeLibrary">Whether to use native BLAS and LAPACK routines, or not.</param>
        /// <returns>A <see cref="Matrix"/> containing the values of <paramref name="vector"/>.</returns>
        /// <remarks><see cref="Settings.DefaultMatrixType"/> determines the storage type to use.
        /// If native routines are used, <see cref="Settings.Blas"/> and <see cref="Settings.Lapack"/> 
        /// set which <see cref="BlasProvider"/> and <see cref="LapackProvider"/> to use, respectively.</remarks>
        /// <exception cref="ArgumentNullException">If <paramref name="vector"/> is <b>null</b>.</exception>
        /// <seealso cref="Settings"/>
        /// <seealso cref="BlasProvider"/>
        /// <seealso cref="LapackProvider"/>        
        public static Matrix CreateMatrix(Vector vector, bool columnVector, bool useNativeLibrary)
        {
            return CreateMatrix(vector, columnVector, Settings.DefaultMatrixType, useNativeLibrary);
        }

        /// <summary>
        /// Creates a <see cref="Matrix"/> from the given <see cref="Vector"/>.
        /// </summary>
        /// <param name="vector">The <see cref="Vector"/> to create the <see cref="Matrix"/> to from.</param>
        /// <param name="columnVector">If <b>true</b>, creates a <b>vector.count x 1</b> <see cref="Matrix"/>;
        /// otherwise, create a creates a <b>1 x vector.count</b> <see cref="Matrix"/>.</param>
        /// <param name="type">The type of matrix to create.</param>
        /// <param name="useNativeLibrary">Whether to use native BLAS and LAPACK routines, or not.</param>
        /// <returns>A <see cref="Matrix"/> containing the values of <paramref name="vector"/>.</returns>
        /// <remarks>If native routines are used, <see cref="Settings.Blas"/> and <see cref="Settings.Lapack"/> 
        /// set which <see cref="BlasProvider"/> and <see cref="LapackProvider"/> to use, respectively.</remarks>
        /// <exception cref="ArgumentNullException">If <paramref name="vector"/> is <b>null</b>.</exception>
        /// <seealso cref="Settings"/>
        /// <seealso cref="BlasProvider"/>
        /// <seealso cref="LapackProvider"/>
        public static Matrix CreateMatrix(Vector vector, bool columnVector, MatrixType type, bool useNativeLibrary)
        {
            if (vector == null)
            {
                throw new ArgumentNullException(dnAnalytics.Resources.Strings.NullParameterException);
            }

            Matrix ret;
            if (columnVector)
            {
                ret = CreateMatrix(vector.Count, 1, type, useNativeLibrary);
                for (int i = 0; i < vector.Count; i++)
                {
                    ret.ValueAt(i, 0, vector[i]);
                }
            }
            else
            {
                ret = CreateMatrix(1, vector.Count, type, useNativeLibrary);
                for (int i = 0; i < vector.Count; i++)
                {
                    ret.ValueAt(0, i, vector[i]);
                }
            }
            return ret;
        }

        /// <summary>
        /// Creates a <see cref="Matrix"/> from the given array.
        /// </summary>
        /// <param name="array">The array to create the <see cref="Matrix"/> to from.</param>
        /// <param name="columnWise"><b>true</b> if the data is layed out column-wise, <b>false</b>
        /// if layed out row-wise.</param>
        /// <param name="rows">The number of rows the <see cref="Matrix"/> to create.</param>
        /// <param name="columns">The number of columns the <see cref="Matrix"/> to create</param>
        /// <returns>A <see cref="Matrix"/> containing the values of <paramref name="array"/>.</returns>
        /// <remarks><see cref="Settings.DefaultMatrixType"/> determines the storage type to use and, <see cref="Settings.UseNativeLibrary"/> 
        /// determines whether to use native BLAS and LAPACK routines or not. If native routines are used, <see cref="Settings.Blas"/> 
        /// and <see cref="Settings.Lapack"/> set which <see cref="BlasProvider"/> 
        /// and <see cref="LapackProvider"/> to use, respectively.</remarks>
        /// <exception cref="ArgumentNullException">If <paramref name="vector"/> is <b>null</b>.</exception>
        /// <exception cref="ArgumentException">If the length of <paramref name="array"/> 
        /// does not equal <b><paramref name="array"/> * <paramref name="columns"/></b>.</exception>
        /// <seealso cref="Settings"/>
        /// <seealso cref="BlasProvider"/>
        /// <seealso cref="LapackProvider"/>
        public static Matrix CreateMatrix(double[] array, int rows, int columns, bool columnWise)
        {
            return CreateMatrix(array, rows, columns, columnWise, Settings.DefaultMatrixType, Settings.UseNativeLibrary);
        }

        /// <summary>
        /// Creates a <see cref="Matrix"/> from the given array.
        /// </summary>
        /// <param name="array">The array to create the <see cref="Matrix"/> to from.</param>
        /// <param name="columnWise"><b>true</b> if the data is layed out column-wise, <b>false</b>
        /// if layed out row-wise.</param>
        /// <param name="rows">The number of rows the <see cref="Matrix"/> to create.</param>
        /// <param name="columns">The number of columns the <see cref="Matrix"/> to create</param>
        /// <param name="type">The type of matrix to create.</param>
        /// <returns>A <see cref="Matrix"/> containing the values of <paramref name="array"/>.</returns>
        /// <remarks><see cref="Settings.UseNativeLibrary"/> 
        /// determines whether to use native BLAS and LAPACK routines or not. If native routines are used, <see cref="Settings.Blas"/> 
        /// and <see cref="Settings.Lapack"/> set which <see cref="BlasProvider"/> 
        /// and <see cref="LapackProvider"/> to use, respectively.</remarks>
        /// <exception cref="ArgumentNullException">If <paramref name="vector"/> is <b>null</b>.</exception>
        /// <exception cref="ArgumentException">If the length of <paramref name="array"/> 
        /// does not equal <b><paramref name="array"/> * <paramref name="columns"/></b>.</exception>
        /// <seealso cref="Settings"/>
        /// <seealso cref="BlasProvider"/>
        /// <seealso cref="LapackProvider"/>
        public static Matrix CreateMatrix(double[] array, int rows, int columns, bool columnWise, MatrixType type)
        {
            return CreateMatrix(array, rows, columns, columnWise, type, Settings.UseNativeLibrary);
        }

        /// <summary>
        /// Creates a <see cref="Matrix"/> from the given array.
        /// </summary>
        /// <param name="array">The array to create the <see cref="Matrix"/> to from.</param>
        /// <param name="columnWise"><b>true</b> if the data is layed out column-wise, <b>false</b>
        /// if layed out row-wise.</param>
        /// <param name="rows">The number of rows the <see cref="Matrix"/> to create.</param>
        /// <param name="columns">The number of columns the <see cref="Matrix"/> to create</param>
        /// <param name="useNativeLibrary">Whether to use native BLAS and LAPACK routines, or not.</param>
        /// <returns>A <see cref="Matrix"/> containing the values of <paramref name="array"/>.</returns>
        /// <remarks><see cref="Settings.DefaultMatrixType"/> determines the storage type to use.
        /// If native routines are used, <see cref="Settings.Blas"/> and <see cref="Settings.Lapack"/> 
        /// set which <see cref="BlasProvider"/> and <see cref="LapackProvider"/> to use, respectively.</remarks>
        /// <exception cref="ArgumentNullException">If <paramref name="vector"/> is <b>null</b>.</exception>
        /// <exception cref="ArgumentException">If the length of <paramref name="array"/> 
        /// does not equal <b><paramref name="array"/> * <paramref name="columns"/></b>.</exception>
        /// <seealso cref="Settings"/>
        /// <seealso cref="BlasProvider"/>
        /// <seealso cref="LapackProvider"/>        
        public static Matrix CreateMatrix(double[] array, int rows, int columns, bool columnWise, bool useNativeLibrary)
        {
            return CreateMatrix(array, rows, columns, columnWise, Settings.DefaultMatrixType, useNativeLibrary);
        }

        /// <summary>
        /// Creates a <see cref="Matrix"/> from the given array.
        /// </summary>
        /// <param name="array">The array to create the <see cref="Matrix"/> to from.</param>
        /// <param name="columnWise"><b>true</b> if the data is layed out column-wise, <b>false</b>
        /// if layed out row-wise.</param>
        /// <param name="rows">The number of rows the <see cref="Matrix"/> to create.</param>
        /// <param name="columns">The number of columns the <see cref="Matrix"/> to create</param>
        /// <param name="type">The type of matrix to create.</param>
        /// <param name="useNativeLibrary">Whether to use native BLAS and LAPACK routines, or not.</param>
        /// <returns>A <see cref="Matrix"/> containing the values of <paramref name="array"/>.</returns>
        /// <remarks>If native routines are used, <see cref="Settings.Blas"/> and <see cref="Settings.Lapack"/> 
        /// set which <see cref="BlasProvider"/> and <see cref="LapackProvider"/> to use, respectively.</remarks>
        /// <exception cref="ArgumentNullException">If <paramref name="vector"/> is <b>null</b>.</exception>
        /// <exception cref="ArgumentException">If the length of <paramref name="array"/> 
        /// does not equal <b><paramref name="array"/> * <paramref name="columns"/></b>.</exception>
        /// <seealso cref="Settings"/>
        /// <seealso cref="BlasProvider"/>
        /// <seealso cref="LapackProvider"/>
        public static Matrix CreateMatrix(double[] array, int rows, int columns, bool columnWise, MatrixType type, bool useNativeLibrary)
        {
            if (array == null)
            {
                throw new ArgumentNullException(dnAnalytics.Resources.Strings.NullParameterException);
            }

            if (array.Length != (rows * columns))
            {
                throw new ArgumentException("array", Strings.ArrayLengthIncorrect);
            }

            Matrix ret = CreateMatrix(rows, columns, type, useNativeLibrary);
            if (columnWise)
            {
                int jindex;
                for (int j = 0; j < columns; j++)
                {
                    jindex = j * rows;
                    for (int i = 0; i < rows; i++)
                    {
                        ret.ValueAt(i, j, array[jindex + i]);
                    }
                }
            }
            else
            {
                int iindex;
                for (int i = 0; i < rows; i++)
                {
                    iindex = i * columns;
                    for (int j = 0; j < columns; j++)
                    {
                        ret.ValueAt(i, j, array[iindex + j]);
                    }
                }
            }
            return ret;
        }

        /// <summary>
        /// Creates an identity <see cref="Matrix"/> of the given order.
        /// </summary>
        /// <param name="order">The order of the <see cref="Matrix"/> .</param>
        /// <returns>An identity <see cref="Matrix"/> of the given order.</returns>
        public static Matrix CreateIdentityMatrix(int order)
        {
            Matrix ret = MatrixBuilder.CreateMatrix(order, MatrixType.Sparse);
            for (int i = 0; i < order; i++)
            {
                ret.ValueAt(i, i, 1);
            }
            return ret;
        }
    }
}
